package com.me.myFramework.myAop.aop200.intercept.method;

import com.me.myFramework.myAop.aop200.advice.method.AfterReturningAdvice;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 自己实现 AOP-200：  <p></p>
 *
 * 执行方法执行前增强逻辑的切面执行类，相当于《模板模式》中的模板方法类
 *
 * @author ME
 * @date 2021/9/26
 */
public class AfterReturningAdviceInterceptor2 implements MethodInterceptor {

    private final AfterReturningAdvice advice;

    public AfterReturningAdviceInterceptor2(AfterReturningAdvice advice) {
        this.advice = advice;
    }

    @Override
    public Object invoke(Method method, Object[] args, Object target) throws Throwable {
        Object retVal = method.invoke(target, args);
        this.advice.afterReturning(retVal, method, args, target);
        return retVal;
    }

    /**
     * 一个代理类中通过责任链实现多切面。增强逻辑的拦截器链 MethodInterceptor（或者 切面链）必须一直传递下去，当前执行的哪一个切面也需要传递下去，    <p>
     * 否则无法确定 该执行目标方法？还是继续执行 advice？以及下一次该执行哪个 advice。
     */
    public Object invoke111(Method method, Object[] args, Object target, List<MethodInterceptor> interceptors, int index) throws Throwable {
        // TODO 冗余的边界判断代码，每个 advice模板方法都需要判断自己是不是最后一个切面，如果不是则继续调用下一个切面。需要再次抽取。
        Object retVal;
        if (index < interceptors.size() - 1) {
            retVal = interceptors.get(++index).invoke111(method, args, target, interceptors, index);
        }
        else {
            retVal = method.invoke(target, args);
        }
        this.advice.afterReturning(retVal, method, args, target);

        return retVal;
    }

}
